#pragma once
#include <stdint.h>
#include <stdio.h>

// 随机数
#define RAND_BYTES_MAX_SIZE	(256)

int gen_random_bytes(uint8_t *buffer, size_t buffer_len);

// 格式化输出
#define print_log() fprintf(stderr, "%s:%d:%s()\n",__FILE__, __LINE__, __FUNCTION__);

int sm2_printf(const char *chars, ...);

int sm2_printf_bytes(const char *chars, const uint8_t *data, size_t data_len);

// asn1_der格式
int asn1_integer_2_der_ex(const uint8_t *d, size_t d_len, uint8_t **out, size_t *out_len);

int asn1_header_to_der(size_t d_len, uint8_t **out, size_t *out_len);

// hex to bytes
int hex2bytes(const char *in, size_t in_len, uint8_t *out, size_t *out_len);

/* Big Endian R/W */
#define GET_U32(p) ((uint32_t)(p)[0] << 24 | (uint32_t)(p)[1] << 16 | (uint32_t)(p)[2] <<  8 | (uint32_t)(p)[3])

#define GET_U64(p) ((uint64_t)(p)[0] << 56 | (uint64_t)(p)[1] << 48 | (uint64_t)(p)[2] << 40 | (uint64_t)(p)[3] << 32 | (uint64_t)(p)[4] << 24 | (uint64_t)(p)[5] << 16 | (uint64_t)(p)[6] <<  8 | (uint64_t)(p)[7])

#define PUT_U32(p,V) ((p)[0] = (uint8_t)((V) >> 24), (p)[1] = (uint8_t)((V) >> 16), (p)[2] = (uint8_t)((V) >>  8), (p)[3] = (uint8_t)(V))

#define PUT_U64(p,V) ((p)[0] = (uint8_t)((V) >> 56), (p)[1] = (uint8_t)((V) >> 48), (p)[2] = (uint8_t)((V) >> 40), (p)[3] = (uint8_t)((V) >> 32), (p)[4] = (uint8_t)((V) >> 24), (p)[5] = (uint8_t)((V) >> 16), (p)[6] = (uint8_t)((V) >>  8), (p)[7] = (uint8_t)(V))

/* Rotate */
#define RO_L32(a,n)  (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
